home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
edit
/
aaem95ma.zip
/
EM.H
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-05
|
33KB
|
700 lines
/* This file is EM.H */
#define VERSION "5 Mar 1995"
/* also update the date at start of README & README.1ST */
#include <std.h>
#include <setjmp.h>
#include <string.h>
#include <ctype.h>
#include <new.h>
#include <pc.h>
#include <dpmi.h>
#include <time.h>
/*-----*/
#define uns unsigned
#define reg register
enum{strsize=1024}; /* must be multiple of 8 */
#define lwand(n) ((n+7)/8) /* wand = bit pattern of which chars are magic */
#define lmagic(n) (((((n)&0x00ffffff)*9+7)>>3)+1) /* length of string+1+wand */
enum{magicsize=lmagic(strsize)};
enum{LF=10,CR=13,esc=27}; /* C '\n' == LF, but PC RET key = CR */
/*-----*/
extern void bitpack(char*s,char*t,int n);
extern void showmoan();
extern volatile void MOAN(char *m);
typedef uns char byte;
extern char CW[strsize],disp[256]; extern jmp_buf *bad,rep;
extern void int10(); extern void int16(); extern void int21();
extern void int33();
/*-----*/
#define namebit(name,member,bit) \
inline int name(){return (member>>bit)&1;}; \
inline void name(reg int i){if(i) member|=(1<<bit); else member&=~(1<<bit);};
/*-----*/
class buffer; class line; class mark; class gp_cur; class region; class macro;
class keyarray; class parsing; class val; class colreg; class var; class Mouse;
struct call_;
typedef void subr(val,val,val); typedef val func(int,val*);
class Subr{public: subr*f; short n,menur,menuc; char*name; short*args;};
class Func{public: func*f; short n,menur,menuc; char*name; short*args;};
/*-----*/
inline int bit(char*s,int i) {return (s[i>>3]>>(7-(i&7)))&1;}
/*-----*/
enum {_typeend=3,_adinf=3,_magic=2,_string=1,_unbound=0,_subr=-1,_macro=-2,
_char=-3,_keyarray=-4,_buffer=-5,_int=-6,_keyseq=-7,_rsvword=-8,_unidfname=-9,
_call=-10,_bad=-11,_Subr=-12,_func=-13,_Func=-14,_ref=-15,_type=-16,
_float=-17,_label=-18,_typebeg=-18};
/* code numbers of types. n>0 (and n==0 if s!=0) == string of n chars */
extern char**keysort;
/*----- a value and what type it is */
class val{public: int n; /* n == ditto, or +ve = string of n chars */
union{keyarray*k; subr*f; macro*m; char*s; buffer*b; int i; struct call_*C;
Subr*S; func*fn; Func*Fn; var*v; float x;};
/* n 2nd field use
>0 char*s -> a string of n chars
0 unbound char*s if s==0 or 1, nothing, else empty string
-1 _subr subr*f -> a function void ....(val,val,val)
-2 _macro macro*m -> a macro
-3 _char int i the char i. 256-511 mean 'alt/special key i&255'
-4 _keyarray keyarray*k -> an array of val's corresponding to key values
-5 _buffer buffer*b -> a buffer
-6 _int int i the integer i
-7 _keyseq char*s -> a keysequence,kept in chars s[1] to s[s[0]-1]
-8 _rsvword int i the i'th reserved_word
-9 _unidfname char*s -> an unidentified word (terminated by '\000')
-10 _call struct call_*C -> base & args of a function call
-11 _bad char*s -> a string describing what was wrong
-12 _Subr Subr*S -> an entry in the table of subr names & info
-13 _func func*fn -> a function val ....(int,val*)
-14 _Func Func*Fn -> an enter in the table of func names & info
-15 _ref var*v a variable
-16 _type int i the name of the type i
-17 _float float x the float x
-18 _label (will only occur in var's)
0x80000000+n char*s -> a magic string of n chars */
inline val(val&K){n=K.n; s=K.s;}; /* works, as all 2nd members are 4 bytes */
inline val(){s=0; n=0;}; /* binding key to each allowed type:- */
inline val(buffer*B){b=B; n=_buffer;}
inline val(float X){x=X; n=_float;};
inline val(char C){i=C; n=_char;};
inline val(byte C){i=C; n=_char;};
inline val(char*S,int t){s=S; n=t;};
inline val(char*t){n=strlen(s=t);};
inline val(int I,int t=_int){i=I; n=t;};
inline val(keyarray&K){k=&K; n=_keyarray;};
inline val(macro*M){m=M; n=_macro;};
inline val(struct call_*I){C=I; n=_call;};
/* inline val(subr*F){f=F; n=_subr;}; */
inline val(Subr*B){S=B; n=_Subr;};
/* inline val(func*F){fn=F; n=_func;}; */
inline val(Func*B){Fn=B; n=_Func;};
inline val(var*V){v=V; n=_ref;};
inline int magic(){return (n&0xff000000)==0x80000000;};
inline int magic(int i){return bit(s+(n&0x00ffffff)+1,i);};
inline int bad(){return n==_bad;};
inline void operator=(buffer*B){b=B; n=_buffer;};
inline void operator=(byte C){i=C; n=_char;};
inline void operator=(char C){i=C; n=_char;};
inline void operator=(char*t){n=strlen(s=t);};
inline void operator=(int I){i=I; n=_int;};
inline void operator=(keyarray&K){k=&K; n=_keyarray;};
inline void operator=(macro&M){m=&M; n=_macro;};
inline void operator=(struct call_*I){C=I; n=_call;};
inline void operator=(const val&t){s=t.s; n=t.n;};
inline void operator=(subr*F){f=F; n=_subr;};
inline int operator<<(int j){return n!=_rsvword?0:i==j;};
inline int operator==(byte C){return n!=_char?0:i==C;};
inline int operator==(subr*F){return n!=_subr?0:f==F;};
inline int operator==(val&F){return F.n==n?F.s==s:0;};
inline int notstring(){return n<0?1:n>0?0:!s;}
int operator==(char*t);
inline val operator-(){return val(-i,_int);}; /* only use with _int's */
char*moanifbound(val K,int jump=1);
Subr*Subrinfo(); char*Subrname();
Func*Funcinfo(); char*Funcname();
int charval();
int operator>>(char c); /* char in string? */
int checktype(int type); val convto(int type);
val copy();
val&keyseq();
val&operator[](int N);
void del();
void expandkeyseq(char*K,int plain=0); /* expand char* into names of keys */
val getifn(val&T,char*prompt,int type=0,char*start=0);
val operator()(); /* obey the val */
int type();
int typ();
void print(char*Z=(char*)_buffer,int pr=1000);
void subarray();
void unbind();
int known_now(); };
inline int ScreenRows() {return *(unsigned char*)0xe0000484+1;}
inline int ScreenCols() {return *(unsigned short*)0xe000044a;}
inline int ScreenMode() {return *(unsigned char*)0xe0000449;}
/*-----*/
inline val kf(subr*F){val f; f.f =F; f.n=_subr; return f;};
inline val ff(func*F){val f; f.fn=F; f.n=_func; return f;};
extern char*copyof(char*s,int n=0);
extern char*copyof(const val&s);
extern char*chname(int c);
extern char*keyname(int c,int alt=0);
extern void Obey(val N=val(1,0));
extern int yesno(char*pt); extern int Yesno(char*s);
/*----- standard header for key-functions */
#define KF(name) void name(val N/*=val(1,0)*/,val T1/*=val()*/,val T2/*=val()*/)
#define Kf(name) extern void name(val N=val(1,0),val T1=val(),val T2=val())
/* if N.n!=0, N.i==repeat count, usually */
#define FN(name) val name(int n,val*arg)
#define fN(name) extern FN(name)
/*----- a detached chain of lines */
class Text{public: line *beg,*end;
inline Text(){beg=end=0;};
inline Text(line*b,line*e){beg=b; end=e;}
inline Text(Text&T){beg=T.beg; end=T.end;};
inline operator=(const Text&T){beg=T.beg; end=T.end;};
Text(val&); void read(char*file); Text copy(); void clear(); /*void print();*/};
/*-----*/
extern Text killring[]; extern short nkill;
/*----- row and column on screen */
class gp_cur{public: byte c,r;
inline gp_cur(byte R=0, byte C=0){c=C; r=R;};
inline gp_cur(gp_cur &d){c=d.c; r=d.r;};
inline void operator=(gp_cur&d){c=d.c; r=d.r;};};
/*-----*/
extern gp_cur cursor; /* the cursor */
extern char *Moan,*Display;
/*----- a position in buffer by line & char */
class mark {public: mark *next,*prev; line *r; short c;
inline mark(line*R=0,short C=0){r=R; c=C;};
inline mark(const mark&m){r=m.r; c=m.c;};
inline void operator=(const mark&m){r=m.r; c=m.c;};
byte operator*(); /* char at mark */
/* move mark 1 char *//* if runs off file, leaves this->r==0 :- */
void operator++(); void operator--();
void operator=(char);
void operator+=(char); void operator+=(char*); void operator+=(buffer*);
line* operator/(int);
void operator!();
void bs();
operator char*();
region yank(const Text&K,int copy=1);
void operator>>=(int n);
void operator<<=(int n);
int Up(); int Down(); int Left(); int Right();
int is_white(); int is_alpha(); int is_alnum();
void find_white(int back=0); void skip_white(int back=0,int Eol=0);
void skip_alpha(int back=0); void find_alpha(int back=0,int Eol=0);
void skip_alnum(int back=0); void find_alnum(int back=0,int Eol=0);
int eol(); int eof(); void Skip();
void skipword(int); int isin(region &R);
int operator<(mark&N); /* are marks in that order? */
inline int operator==(const mark&N){if(r==N.r) if(c==N.c) return 1; return 0;};
inline int operator!=(const mark&N){if(r==N.r) if(c==N.c) return 0; return 1;};
friend region operator-=(const mark&M,const mark&N);
friend region operator-(const mark&M,const mark&N);
inline friend void operator^(mark&M,mark&N){M.next=&N; N.prev=&M;};
void push(); void hsup(); void pop();
void skipsentence(int); void skippara(int);
int thisch(char C); int string(val s); /* parsing:- */
val elem(); /* P.elem() : look for an element, move P over text parsed */
val name(); val label(); val number(); val string(); val expr(int prio=0);
val monexpr_upto(int); val Call(); val decl();
char*op(int);};
extern int heremagic(mark A,val T);
extern int here(mark A,val T,int w=0);
/*----- two marks */
class region{public: mark beg,end;
inline region(){beg=mark(0,0); end=mark(0,0);};
inline region(const mark &B,const mark &E){beg=B; end=E;};
inline void operator=(const region&R){beg=R.beg; end=R.end;};
mark Delete(int query=1); mark kill(int query=1); void copykill();
void format();
int huntf(val T,int word=0); int huntb(val T,int word=0);
inline int hunt(val T,int back=0,int w=0){return back?huntb(T,w):huntf(T,w);};
void replace(val Old,val New,int ask=0,int word=0);
region moveto(mark &M); region copyto(mark &M); region repl(Text&k,int copy=1);
void right_order(); void color(int f,int b); void Case(int);
int ok_to_delete(); void expandtabs(); void maketabs(); };
/*----- M-=N == the region defined by the marks M & N */
inline region operator-=(const mark&M,const mark&N){return region(M,N);}
/*----- ditto, make sure that M <= N */
inline region operator-(const mark&M,const mark&N){
region R(M,N); R.right_order(); return R;}
/*----- a line in a buffer */
class line {public:
line *next; /* -> the next line */
line *prev; /* -> the previous line */
short n; /* chars in line */
char *s; /* the line, physically has (n+15)&~15 bytes */
char info;
short sl; /* current screen line number (line_notshown == not on screen) */
namebit(la,info,0); /* if line altered since last displayed */
namebit(no_cr,info,1) /* if no CR before LF at end of this line */
#define line_notshown 0x4000
inline void nullline(){next=prev=0; s=0; n=0; info=0; la(1); sl=line_notshown;};
inline line(){nullline();}; /* empty line */
line(char*s); line(char*s,int n); line(line*L); ~line();
void operator-(); /* remove previous eol */
void operator--(); /* remove next eol */
void operator-(Text&); /* remove next eol, in a Text */
void display(int i); int dispfold(int i); int nparts(int c=-1); int showeol();
friend inline void operator-(reg line &A,reg line &B){A.next=&B; B.prev=&A;};
/* link lines A and B */
friend line* operator/ (line &L,val t); /* insert line after line L */
friend line* operator/ (val t,line &L); /* insert line before line L */
void operator= (val t); /* replace text of line */
void operator+=(char c); /* append char to line */
void operator+=(line &M); /* append text of M to line */
void operator= (int n); /* change line.n */
void operator+=(int n); void operator-=(int n); /* ditto */
char operator[](int n); /* nth char in line */
void empty(); /* delete all text in line */
int to_tabexp(int,int=0); int from_tabexp(int,int=0);
int to_scrcolno(int); /* char # to screen col # */
int from_scrcolno(int); /* screen col # to char # */
int blank(); /* if line is blank */
void dotty(); /* check dot.c */
void split_if_long(); void de_trailing_space();
int is_bop(); int is_eop(); int lineno(); void del(); };
/*-----*/
extern line*dustbin; extern void emptydustbin();
extern line *line0,*modeline; /* dummy lines */
inline byte mark::operator*(){return c>=r->n?LF:r->s[c];} /* char at mark */
inline int mark::eol(){return c>=r->n;}
inline int mark::eof(){return r->next?0:c>=r->n;}
inline void mark::operator++(){if(++c>r->n) {c=0; r=r->next;}}
inline void mark::operator--(){if(--c<0) c=(r=r->prev)?r->n:0;}
/*-----*/
class screenline{public:line *l,*nl; int lp,nlp,np,lc,ok,nc; uns short*sa;
buffer*buf;};
/*-----*/
extern screenline Sl[];
/*----- text to be displayed colored */
class colreg {public: int fg,bg; region Reg;
inline init() {fg=bg=0; Reg.beg=mark(0,0); Reg.end=mark(0,0);};
inline colreg() {init();};};
/*** I must keep track of these marks on any text changes */
/*-----*/
class buffer {public:
buffer *next; /* next buffer */
mark start; /* -> top left char on screen */
int startc; /* backup for start.c */
int stback; /* if fold long lines, where in start.r to start */
mark dot; /* cursor */ /* start of chain of marks */
mark olddot; /* where dot was at start of current mouse operations */
mark dot1,dot2; /* where dot was before last command */
byte row1; /* first row of screen used by buffer */
byte lastrow; /* last row of screen used by buffer */
byte nrows; /* # of rows of text on screen incl. info line */
byte ncols; /* # of cols of text on screen */
short dotcc,dotcc2; /* screen col # of dot */
line text; /* completes circle of lines */
byte truncated,invisible,readonly,changed,oldch,refresh; /* flags */
byte overlay,tabtype,twod,wrap,Case,longlines,skip_after_word; /* modes */
#define buffer_nmodes 7
int rmargin,sortcol;
char *name; /* file name */ val bound;
colreg col;
void initbuffer(); inline buffer(){initbuffer();};
buffer(char*F,int rd=1); /* new buffer opened on file F */
~buffer();
line* operator[](int); /* ith line in buffer */
void deltext(); buffer*linkin();
void read(); void write(); void clearscreen();
void go_to(); void operator()(int N=0);
inline mark bof(){return mark(text.next,0);};
inline mark eof(){return mark(text.prev,text.prev->n);};
int nmarks(); mark&Mark(int); void display(); void dispfold(int d=0);
void rem1mark(); void up(); void down(); void left(); void right();
void split_window_with(int N);
inline void operator+=(char c){dot+=c;}; /* insert at dot */
inline void operator+=(char*s){dot+=s;}; /* insert at dot */
void redraw_info(); int exists(); void bind(val*f,val T1); };
/*-----*/
extern buffer *buf0, *bhead, *B; extern int bcount; /* B -> current buffer */
extern line *T; /* entry point of circle of lines currently being handled */
/*-----*/
#define forallbufs(b) for(b=bhead;b;b=b->next)
#define forallmarks(M) for(M=&B->start;M;M=M->next)
/* buffer has extra final empty line unless last char in file is not LF */
/*-----*/
extern char DIR[];
#define HELPFILE "HELP"
#define BIGHELPFILE "HELP.BIG"
#define DICTFILE "DICT"
extern char helpfile[],bighelpfile[],**infohelp,**infobig;
extern char**Subrhelp(char*name);
/*-----*/
extern char T1w[],T2w[],Filename[]; extern val T1t,T2t,Fn,specialchars;
extern int needswrap;
enum {ob_kill=1,ob_yank,ob_other};
extern int obtype,prevobtype; extern region lastyank;
extern buffer*window[]; extern int nwindows,currentwindow;
extern long _ax,_bx,_cx,_dx,_si,_di,_bp,_es; extern short _flags;
#define _carry (_flags&1)
#define _zeroflag (_flags&0x40)
/*-----*/
#define __SR() /* save the registers */ ({asm("xchgl %eax,__ax"); \
asm("xchgl %ebx,__bx"); asm("xchgl %ecx,__cx"); asm("xchgl %edx,__dx"); \
asm("xchgl %esi,__si"); asm("xchgl %edi,__di"); asm("xchgl %ebp,__bp"); })
#define __RR() /* restore the registers */ ({ \
asm("pushf"); asm("popw __flags"); __SR();})
/*-----*/
enum Color{Black=0,Blue=1,Green=2,Cyan=3,Red=4,Magenta=5,Orange=6,White=7};
/*-----*/
extern byte gp_Mode,gp_Rows,gp_Cols;
extern short gp_Attr,gp_Attr_def; /* on black */
inline uns short sch(byte C,byte A){return C|(A<<8);}
#define screen ((uns short*)ScreenPrimary)
#define scr(row,col) (screen[(col)+(row)*gp_Cols])
extern int getkey();
extern int get_key(); extern int nextch;
extern byte get__key();
extern int getkey_nowait();
extern int typahead();
extern int inject(int ch);
extern void printch(char c);
extern int beep();
extern int gp_mode(void);
extern void gp_mode(char m);
extern void gp_cursor(gp_cur c);
inline void gp_cursor(int r,int c) {gp_cursor(gp_cur(r,c));}
extern gp_cur gp_cursor(void);
extern void gp_clear(int i=0,int j=0,int J=gp_Cols-1);
/*-----*/
/* the attribute of a displayed character: bc,fc = back- & foreground colors */
/* fc add 8 for bright; */
inline short Attrib(int fc,int bc=Black,int flash=0) {
return ((fc&15)<<0)|((bc&7)<<4)|((flash&1)<<7);}
/* typedef struct {int fc:3, bright:1, bc:3, blink:1; } gp_Attrib; */
/*-----*/
/*** special keys. Some of these may be different on different PC's ****/
enum {alt_0=129, alt_1=120, alt_2=121, alt_3=122, alt_4=123, alt_5=124,
alt_6=125, alt_7=126, alt_8=127, alt_9=128, alt_A=30, alt_B=48, alt_C=46,
alt_D=32, alt_E=18, alt_F=33, alt_G=34, alt_H=35, alt_I=23, alt_J=36, alt_K=37,
alt_L=38, alt_M=50, alt_N=49, alt_O=24, alt_P=25, alt_Q=16, alt_R=19, alt_S=31,
alt_T=20, alt_U=22, alt_V=47, alt_W=17, alt_X=45, alt_Y=21, alt_Z=44,
alt_apostr=40, alt_bksp=14, alt_comma=51, alt_del=163, alt_downarrow=160,
alt_end=159, alt_equals=131, alt_esc=1, alt_f10=113, alt_f11=139, alt_f12=140,
alt_f1=104, alt_f2=105, alt_f3=106, alt_f4=107, alt_f5=108, alt_f6=109,
alt_f7=110, alt_f8=111, alt_f9=112, alt_fullstop=5, alt_grave=41, alt_home=151,
alt_insert=162, alt_leftarrow=155, alt_leftsq=26, alt_minus=130,
alt_padminus=74, alt_padplus=78, alt_padslash=164, alt_padstar=55,
alt_pagedown=161, alt_pageup=153, alt_ret=28, alt_rightarrow=157,
alt_rightsq=27, alt_semicolon=39, alt_sharp=43, alt_slash=53, alt_tab=165,
alt_uparrow=152, ctrl_2=3, ctrl_del=147, ctrl_downarrow=145, ctrl_end=117,
ctrl_f10=103, ctrl_f11=137, ctrl_f12=138, ctrl_f1=94, ctrl_f2=95, ctrl_f3=96,
ctrl_f4=97, ctrl_f5=98, ctrl_f6=99, ctrl_f7=100, ctrl_f8=101, ctrl_f9=102,
ctrl_home=119, ctrl_insert=146, ctrl_leftarrow=115, ctrl_pad5=143,
ctrl_padminus=142, ctrl_padplus=144, ctrl_padslash=149, ctrl_padstar=150,
ctrl_pagedown=118, ctrl_pageup=132, ctrl_rightarrow=116, ctrl_tab=148,
ctrl_uparrow=141, del=83, downarrow=80, end=79, f10=68, f11=133, f12=134, f1=59,
f2=60, f3=61, f4=62, f5=63, f6=64, f7=65, f8=66, f9=67, home=71, ins=82,
leftarrow=75, pad5=76, pagedown=81, pageup=73, rightarrow=77, sh_f10=93,
sh_f11=135, sh_f12=136, sh_f1=84, sh_f2=85, sh_f3=86, sh_f4=87, sh_f5=88,
sh_f6=89, sh_f7=90, sh_f8=91, sh_f9=92, sh_tab=15, uparrow=72, lbutton=255,
mbutton=254, rbutton=253, lbuttond=252, mbuttond=251, rbuttond=250,
mousemove=249};
/*-----*/
extern char *altnames[256],*altshortnames[256]; extern val keynames[];
extern char* fullfilename(char*full,char*name);
/*-----*/
inline int bytes(char*s){return *(int*)s;}
/*----- to next multiple of 16 */
inline uns int roundup(uns int i) {return ((i)+15)&((uns int)0xfffffff0);}
/*----- copy n chars from t to s */
extern char* Copytext(char*s,char*t,int n);
/* extern char* copy_text(char*s,char*t,int n); */
/*-----*/
/* {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0e,0x0f,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1e,0x1f,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2e,0x2f,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3e,0x3f,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4e,0x4f,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5e,0x5f,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6e,0x6f,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7e,0x7f,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8e,0x8f,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9e,0x9f,
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xae,0xaf,
0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xce,0xcf,
0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xde,0xdf,
0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xee,0xef,
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfe,0xff}; */
/*----- compare n chars from t to s */
int comptext(reg char*s,reg char*t,int n,int nocase=0);
/*-----*/
#define add_to_list(head,item) ((item)->next=(head), (head)=(item))
#define remove_from_list(head,item) ({typeof(item) *I; \
for(I=&(head);*I;I=&((*I)->next)) if(*I==(item)) {*I=(*I)->next; break;}})
/*-----*/
/*** make fault remarks without mallocking, in case fault was 'out of store' */
/*----- change color of jth char of ith screen line */
extern void recolor(int i,int j,int col);
/*----- display string s on screen line n (displayn = do not clear to eol) */
extern int displayn(val T,int n,int c,int fc=White,int bc=Black);
extern int displayn(char*s,int n,int c,int fc=White,int bc=Black);
extern void display(val T,int n,int c,int fc=White,int bc=Black);
extern void display(char*s,int n,int c,int fc=White,int bc=Black);
extern void clearscreen();
extern void getstring(char*pt,int Sl,val &T,int max,int type=0);
/*-----*/
extern char chwidth[256];
extern byte to__upper[256],to__lower[256]; extern char chtype[256];
enum{c_alpha=1,c_alnum=2,c_white=4};
/*-----*/
#define to_upper(c) to__upper[(byte)(c)]
#define to_lower(c) to__lower[(byte)(c)]
/*----- x==y ignoring case? */
#define cheq(x,y,Case) (Case?((x)==(y)):to_upper(x)==to_upper(y))
#undef iswhite
#undef isalpha
#undef isalnum
#define iswhite(c) (chtype[(byte)(c)]&c_white)
#define isalpha(c) (chtype[(byte)(c)]&c_alpha)
#define isalnum(c) (chtype[(byte)(c)]&c_alnum)
inline int mark::is_white(){return iswhite(c>=r->n?LF:r->s[c]);}
inline int mark::is_alpha(){return isalpha(c>=r->n?LF:r->s[c]);}
inline int mark::is_alnum(){return isalnum(c>=r->n?LF:r->s[c]);}
/*-----*/
extern region Found;
/*-----*/
typedef struct call_{char n,pr,*name; int type; val arg[1];} call;
extern call*call_n(int n,int type,int pr,char*name,val*a);
/*----- array of n key bindings to look up in */
class keyarray {public:val*a; long n; void subarray();
inline keyarray(){a=0; n=0;}; val&operator[](int i);
void search(void(*fn)(val&k));
void print(int N=1,int i=1,int deep=1); };
/*-----*/
extern val key0; extern keyarray keys; /* head of lookup tree of key bindings */
/*----- one statement in a macro. Contains keybinding and numeric arg */
class macstep{public: macstep *next; val f,N,T1,T2; /* like a call of a subr */
inline macstep(val k=val(),val n=val(1,0),val t1=val(),val t2=val()){
f=k; N=n; next=0; T1=t1; T2=t2; next=0;};
inline void operator=(macstep &m){f=m.f; N=m.N; T1=m.T1; T2=m.T2;}
inline macstep(macstep &m){f=m.f; N=m.N; T1=m.T1; T2=m.T2;}
void operator()(int n=1); /* obey */
void print(); /* print macstep into buffer text */
void del(); macstep*copy();
inline void clear(){f.n=T1.n=T2.n=0; N=val(1,0); f.s=T1.s=T2.s=0;};
inline ~macstep(){del();} };
extern macstep laststep,thisstep;
inline macstep*macstep::copy(){return new macstep(f,N,T1.copy(),T2.copy());};
#define setrec(x,y) ({if(!play) thisstep.x=(y);})
#define setrek(x,y) ({if(!play) thisstep.x=val(y);})
#define setref(x,y) ({if(!play) thisstep.x=kf(y);})
/*-----*/ /* offset+=0x80000000 if global */
class var{public: var*next; char*name; long int type,offset;
inline var(char*Name,int Type,int Offset,var*Next=0){
name=copyof(Name); type=Type; offset=Offset; next=Next;};
inline ~var(){delete name; if(next) delete next;};};
extern var*globvars; extern int nglobvars;
void prvars(var*v);
/*----- macro header */
extern macro *record,*Macro,*macros;
class macro{public: macstep *last,*text; val bound; macro*next; char*name;
int nvars; var*vars;
inline val&f(){return *(val*)&last;};
inline macro(){last=text=0; bound=val(); next=macros; macros=this; name=0;
nvars=0; vars=0;};
void operator+=(macstep*m); /* append step to macro */
void operator()(val N=val(1,0),int r=0); /* obey, arg=N, r = recursion depth */
void print(); /* print macro on buffer text */
void tidy(); /* e.g. chain up successive insert-a-character's */
void empty(); ~macro(); };
extern int macdepth; extern char*CMN; extern macstep _lazy;
/*-----*/
class macrinfo{public: macstep*prevstep; val*stack; int nvars; byte rec;
inline macrinfo(){prevstep=&_lazy; rec=1; stack=0; nvars=0;};
inline val&operator[](int i){return stack[(i>?0)<?(nvars-1)];};
inline ~macrinfo(){delete stack;};};
extern macrinfo basemi,*mi;
#define play (mi!=&basemi)
/*-----*/
inline byte keysdown(){_ax=0x0200; int16(); return _ax&255;}
enum {k_rshift=1, k_lshift=2, k_ctrl=4, k_alt=8, /* these 4 pressed */
k_scrlock=16, k_numlock=32, k_capslock=64, k_insert=128, /* these 4 toggle */
k_break=14 /* alt & ctrl & left shift */ };
extern int loseip();
inline int Breakin(){_ax=0x0200; int16(); return (_ax&14)==14?loseip():0;}
/*-----*/
extern subr*keep[]; extern char keyseqc[];
extern val keyseq; /* work space */
extern char rec; /* whether to record this step */
/*-----*/
extern void Insert(int N,byte c);
extern void Replace(int N,int D,val T1,val T2,char *pt,int ask,int word);
extern void search(int N,int D,val T1,char*prompt,int back=0,int word=0);
extern void incrsearch(int N,int D,char*pt,int back=0);
extern void readescno(short c);
extern void readaltno(short c);
extern byte &bufmode(int i,buffer*BB=0);
/*-----*/
extern char**dispmode[];
extern void(*cf[])(int,byte);
extern subr*cff[];
/*-----*/
extern void insert_(int N,byte c);
extern void overlay_(int N,byte c);
extern void nomove_(int N,byte c);
extern void forallkeys(void Subr(val*),int L=1,keyarray&K=keys);
extern void moan_if_no_help(val*f);
extern void prbuffer(buffer*C);
extern void print_subr(val*f);
extern Subr*namedsubr(val name);
extern val*getk(val arg,char*prompt=0);
/*-----*/
extern void translate(buffer*BB);
extern buffer*buf_named(val name);
extern int findbuf_new(val&name,int read=1);
extern buffer*findbuf(val name);
extern region thisword(int N=1);
extern region thispara();
extern void casechange(int N,line*L,int b,int e);
/*-----*/
extern val eosentchars; extern byte ccc; extern char rept;
extern Subr subrname[]; extern Func funcname[];
/*-----*/
Kf(_idle); Kf(accentedletters); Kf(alt0); Kf(alt1); Kf(alt2); Kf(alt3);
Kf(alt4); Kf(alt5); Kf(alt6); Kf(alt7); Kf(alt8); Kf(alt9); Kf(altminus);
Kf(backspace); Kf(beginmacro); Kf(bindkeybuf); Kf(bindkeymacro);
Kf(bindkeysubr); Kf(buffer_); Kf(buffermenu); Kf(calldos); Kf(callsubr);
Kf(capitalize); Kf(casemode); Kf(cbrackets); Kf(cccmode); Kf(cchrstr);
Kf(checkhelp); Kf(checkspelling); Kf(copybufmodes); Kf(copydir); Kf(copykill);
Kf(copytext); Kf(cstrchr); Kf(delblanklines); Kf(delbuf); Kf(delet);
Kf(deletewhite); Kf(dis_play); Kf(displayhex); Kf(emptyappendix); Kf(endmacro);
Kf(esc0); Kf(esc1); Kf(esc2); Kf(esc3); Kf(esc4); Kf(esc5); Kf(esc6); Kf(esc7);
Kf(esc8); Kf(esc9); Kf(escminus); Kf(expandtabs); Kf(finalcr); Kf(findb);
Kf(findf); Kf(findwordb); Kf(findwordf); Kf(finish); Kf(formatinsetregion);
Kf(formatpara); Kf(formatregion); Kf(getappendix); Kf(godown); Kf(godownpart);
Kf(goleft); Kf(goright); Kf(gotobof); Kf(gotobol); Kf(gotocol); Kf(gotodir);
Kf(gotoeof); Kf(gotoeol); Kf(gotoline); Kf(gotonbuf); Kf(goup); Kf(gouppart);
Kf(go_to); Kf(help); Kf(If); Kf(incrfindb); Kf(incrfindf); Kf(insert);
Kf(insertfile); Kf(insertspaces); Kf(kill_to_eol); Kf(killregion); Kf(killsent);
Kf(killwordb); Kf(killwordf); Kf(leaveonewhite); Kf(linefeed); Kf(literalchar);
Kf(longlinesmode); Kf(lwcaseregion); Kf(lwcasewords); Kf(macromenu);
Kf(maketabs); Kf(markbof); Kf(markeof); Kf(menu); Kf(mergefile); Kf(modemenu);
Kf(mouse_mode); Kf(mouse_move); Kf(movetext); Kf(namemacro); Kf(newline);
Kf(nextwindow); Kf(nofinalcr); Kf(nomove); Kf(obey); Kf(onewindow);
Kf(openfile); Kf(openline); Kf(overlay); Kf(overlaymode); Kf(page_down);
Kf(page_up); Kf(popmark); Kf(prbindings); Kf(prbuffers); Kf(prevwindow);
Kf(prkeynames); Kf(prkeys); Kf(prmacro); Kf(prmacros); Kf(prsubrnames);
Kf(pushmark); Kf(putappendix); Kf(readmacros); Kf(refresh_display); Kf(remmark);
Kf(renamebuffer); Kf(repeat); Kf(repl); Kf(replask); Kf(replword);
Kf(replwordask); Kf(replyank); Kf(restorebuf); Kf(savebuffer); Kf(setmark);
Kf(setolddot); Kf(setrightmargin); Kf(setsortcol); Kf(showinfo); Kf(showregion);
Kf(skipafterwordmode); Kf(skipparab); Kf(skipparaf); Kf(skipsentb);
Kf(skipsentf); Kf(skipwordb); Kf(skipwordf); Kf(sortlines); Kf(splitwindow);
Kf(swopmark); Kf(tabmode); Kf(tabulate); Kf(times4); Kf(twiddle);
Kf(twiddlelines); Kf(twiddlewords); Kf(twodmode); Kf(unbindkey);
Kf(upcaseregion); Kf(upcasewords); Kf(version); Kf(whoa); Kf(wrapmode);
Kf(writebuffer); Kf(yank);
/*-----*/
fN(_allocate); fN(_andthen); fN(_divide); fN(_minus); fN(_neg); fN(_plus);
fN(_eq); fN(_ne); fN(_ge); fN(_le); fN(_gt); fN(_lt);
fN(_same); fN(_times); fN(currentbuffer); fN(keyseq_);
/*-----*/
extern void start_an_arg();
extern val&getkeyseq(val P);
inline val&getkeyseq(char*P) {return getkeyseq(val(P,strlen(P)));}
/*-----*/
extern byte esc_alt[26];
extern char*getstringhelp[];
extern char*rsvword[],**info;
/*-----*/
extern void out_of_store();
extern void showmoan();
extern int fileexists(char*);
extern Subr*subrmenu(char*s);
extern Func*funcmenu(char*s);
extern byte drive();
extern void getcurrentdir(char c,char*s);
extern void refreshscreen();
extern buffer*buffer_menu(char*prompt);
extern void filefromdirmenu(val&Dir,char*prompt,char*at=0);
extern int attrib(char*file);
extern buffer*get_file(val&T,char*prompt);
extern unsigned long filesize(char*name);
extern void bitpack(char*s,char*t,int n);
extern void bitexp(char*s,char*t,int n);
extern void bitcopy(char*s,char*t,int n);
extern int charfrommenu();
extern void del_every(val f,keyarray&ka);
extern void del_every(val f,val&m);
extern void del_every(val f,macstep*M);
extern void del_every(val f);
extern void wr(char*s);
extern int display_op_uses();
/*-----*/
#define totab(i) (((i)|7)+1) /* next tab position after i */
#define sptotab(i) (7-((i)&7))
/* how many spaces (not inclusive) from i to next tab position after i */
/*-----*/
extern char*pr(char*B,char*F0,...);
extern char*pa(char*B,char*F0,...);
extern void pf(int f,char*F0,...);
extern void pb(char*F0,...);
extern void ps(char*F0,...);
extern void p_r(char*S,char*F0,...);
extern char*pr_(char*S,char*F0,int*args);
extern char**readtext(char*file);
extern val named(val name);
extern int byteq(char*a,char*b,int n);
extern int check_spelling(char*ws,int wl);
extern int&appendixsize;
extern char*dictname;
extern short*screendump();
extern void screenrestore(short*s);
extern int deletebuffer(buffer*C);
extern void*myalloc(int i);
extern void counterchange(uns short&x);
extern int linewhere(mark M);
extern macro*macro_menu();
extern int bottommenu(
char*prompt,int nrb,char*codes,char**names,int L=8,int defolt=0);
/*-----*//* MOUSE */
#define Regs _go32_dpmi_registers
extern void event(Regs*R);
extern int int86dpmi(int intno);
extern Regs R;
#define Int int86dpmi
/*-----*/
class mousestate {public: int x,y,xe,ye; char visible,mc,bd;
inline mousestate(){};
void operator=(Mouse&);};
/*-----*/
class Mouse {public: int x,y,xe,ye,ldx,ldy,mdx,mdy,rdx,rdy;
char nbuttons,buttons,visible,handlerInstalled,mc,bd;
void show();
void hide();
void read();
void move(int Y,int X);
inline Mouse(){};
void setup();
void operator=(mousestate&);
void settrap(uns int,void (*func)(Regs *));
void range(int ye,int xe);
~Mouse();};
/*-----*/
extern Mouse Jerry; extern int oldmx,oldmy; enum{LB=1,MB=4,RB=2};
/*-----*/
/* extern int debug;
inline void prdeb(char*s) {write(debug,s,strlen(s));}
#define DEBUG debug=open("t$debug",0x0802)
#define GUBED close(debug) */
//#include <stdio.h>
//extern FILE*debug;
//inline void prdeb(char*s) {fprintf(debug,"%s",s);}
//#define DEBUG debug=fopen("t$debug","a")
//#define GUBED fclose(debug)
//#define longjmp(x,y) ({DEBUG; fprintf(debug,"line %1d of "__FILE__":\
// longjmp("#x","#y");\n",__LINE__); GUBED; longjmp(x,y);})
//#define setjmp(x) ({DEBUG; int miaow; fprintf(debug,"line %1d of "__FILE__":\
// setjmp("#x"); set up\n",__LINE__);\
// if(miaow=setjmp(x)) fprintf(debug,"line %1d of "__FILE__":\
// setjmp("#x"); jumped to\n",__LINE__); GUBED; miaow;})